package com.jie.encryption.utils;


import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA加、解密算法工具类
 */
public class RsaUtil {

    /**
     * 加密算法AES
     */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 算法名称/加密模式/数据填充方式
     * 默认：RSA/ECB/PKCS1Padding
     */
    private static final String ALGORITHMS = "RSA/ECB/PKCS1Padding";

    /**
     * Map获取公钥的key
     */
    private static final String PUBLIC_KEY = "publicKey";

    /**
     * Map获取私钥的key
     */
    private static final String PRIVATE_KEY = "privateKey";

    /**
     * RSA 位数 如果采用2048 上面最大加密和最大解密则须填写:  245 256
     */
    private static final int INITIALIZE_LENGTH = 2048;

    /**
     * 后端RSA的密钥对(公钥和私钥)Map，由静态代码块赋值
     */
    private static Map<String, Object> genKeyPair = new HashMap<>();

    static {
        try {
            genKeyPair.putAll(genKeyPair());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成密钥对(公钥和私钥)
     */
    public static Map<String, Object> genKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        KeyPair keyPair = generator.generateKeyPair();
        //公钥
        keyMap.put(PUBLIC_KEY, keyPair.getPublic());
        //私钥
        keyMap.put(PRIVATE_KEY, keyPair.getPrivate());
        return keyMap;
    }

    /**
     * 获取私钥
     */
    public static PrivateKey getPrivateKey() {
        return (PrivateKey) genKeyPair.get(PRIVATE_KEY);
    }

    /**
     * 获取公钥
     */
    public static String getPublicKey() {
        Key key = (Key) genKeyPair.get(PUBLIC_KEY);
        return Base64.encodeBase64String(key.getEncoded());
    }

    /**
     * 公钥加密
     * @param data
     * @param publicKeyBase64
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String data, String publicKeyBase64) throws Exception {
        // 将Base64编码的公钥字符串转换为PublicKey对象
        byte[] publicKeyBytes = Base64.decodeBase64(publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 加密数据
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        // 使用 Base64 编码加密后的字节数组
        return Base64.encodeBase64String(encryptedBytes);
    }
    /**
     * 私钥解密
     * @param encryptedDataBase64
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decryptData(String encryptedDataBase64, PrivateKey privateKey) throws Exception {
        byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedData = cipher.doFinal(encryptedData);
        return new String(decryptedData, "UTF-8");
    }
}